package com.iceGame;

import java.beans.DesignMode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Vector;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.Xml;

public class Level {
	public IceCube iceCube;
	public DestinationObject destination;
	public Vector<CollectableGameObject> collectables;
	public Vector<ObstacleGameObject> obstacles;
	public Vector<Sign> signs;
	public ArrayList<Fireball> fireballs;
	public float gravity;
	public float meltDownRate;
	public String mapFile;
	public String collisionFile;
	public int levelWidth;
	public int levelHeight;
	public Vector2 startPos;
	public Vector2 destinationPos;
	public PhysicsWorld world;
	public float meltAmount;
	public int levelNumber;
	public float twoCubesScore;
	public float threeCubesScore;
	public ArrayList<MovingPlatform> movingPlatforms;
	public ArrayList<Fire> fires;
	private Level(PhysicsWorld world)
	{
		this.world = world;
	}
	public static Level loadLevel(FileHandle LevelFile,final PhysicsWorld world){
		final Level level = new Level(world);
		level.collectables = new Vector<CollectableGameObject>();
		level.obstacles = new Vector<ObstacleGameObject>();
		level.fireballs = new ArrayList<Fireball>();
		level.movingPlatforms = new ArrayList<MovingPlatform>();
		level.fires = new ArrayList<Fire>();
		level.signs = new Vector<Sign>();
		try{
			new Xml(){
				Stack<String> currBranch = new Stack<String>();
				float y;
				float x;
				float delay;
				float size;
				float width;
				float height;
				float entX;
				float entY;
				float entWidth;
				float entHeight;
				float velocity;
				int signType;
				CollectableGameObject colletable;
				Fireball fireball;
				Sign sign;
				MovingPlatform movingPlatform;
				ObstacleGameObject obstacle;
				ArrayList<Location> waypoints;
				@Override protected void open(String name){
					currBranch.push(name);
					if ("Fireball".equals(name)){
						waypoints = new ArrayList<Location>();
					}
					else if ("MovingPlatform".equals(name)){
						waypoints = new ArrayList<Location>();
					}
				}
				@Override protected void attribute (String name, String value) {
					String element = currBranch.peek();
					if ("StartPosition".equals(element)){
						if ("X".equals(name)){
							x = Float.parseFloat(value);
						}
						else if ("Y".equals(name)){
							y = Float.parseFloat(value);
						}
						else if("Size".equals(name)){
							size = Float.parseFloat(value);
						}
					}
					else if ("Destination".equals(element)){
						if ("X".equals(name)){
							x = Float.parseFloat(value);
						}
						else if ("Y".equals(name)){
							y = Float.parseFloat(value);
						}
						else if ("Width".equals(name)){
							width = Float.parseFloat(value);
						}
						else if("Height".equals(name)){
							height = Float.parseFloat(value);
						}
						if ("entX".equals(name)){
							entX = Float.parseFloat(value);
						}
						else if ("entY".equals(name)){
							entY = Float.parseFloat(value);
						}
						else if ("entWidth".equals(name)){
							entWidth = Float.parseFloat(value);
						}
						else if("entHeight".equals(name)){
							entHeight = Float.parseFloat(value);
						}
						
					}
					else if ("Level".equals(element)){
						if ("MapFile".equals(name)){
							level.mapFile = value;
						}
						else if ("CollisionFile".equals(name)){
							level.collisionFile = value;
						}
						else if ("levelWidth".equals(name)){
							level.levelWidth = Integer.parseInt(value);
						}
						else if ("levelHeight".equals(name)){
							level.levelHeight = Integer.parseInt(value);
						}
						else if ("levelNumber".equals(name)){
							level.levelNumber = Integer.parseInt(value);
						}
					}
					else if ("Fire".equals(element)){
						if ("X".equals(name)){
							x = Float.parseFloat(value);
						}
						else if ("Y".equals(name)){
							y = Float.parseFloat(value);
						}
						else if ("Size".equals(name)){
							size = Float.parseFloat(value);
						}
					}
					else if ("CollectableIce".equals(element)){
						if ("X".equals(name)){
							x = Float.parseFloat(value);
						}
						else if ("Y".equals(name)){
							y = Float.parseFloat(value);
						}
						else if ("Size".equals(name)){
							size = Float.parseFloat(value);
						}
					}
					else if ("Sign".equals(element)){
						if ("X".equals(name)){
							x = Float.parseFloat(value);
						}
						else if ("Y".equals(name)){
							y = Float.parseFloat(value);
						}
						else if ("Width".equals(name)){
							width = Float.parseFloat(value);
						}
						else if ("Height".equals(name)){
							height = Float.parseFloat(value);
						}
						else if ("Type".equals(name)){
							signType = Integer.parseInt(value);
						}
					}
	
					else if ("WorldData".equals(element)){
						if ("Gravity".equals(name)){
							level.gravity = Float.parseFloat(value);
						}
						else if ("meltTimer".equals(name)){
							level.meltDownRate = Float.parseFloat(value);
						}
						else if ("meltAmount".equals(name)){
							level.meltAmount = Float.parseFloat(value);
						}
						else if ("twoCubesScore".equals(name)){
							level.twoCubesScore = Float.parseFloat(value);
						}
						else if ("threeCubesScore".equals(name)){
							level.threeCubesScore = Float.parseFloat(value);
						}
					}
					else if ("Fireball".equals(element)){
						if ("Width".equals(name)){
							width = Float.parseFloat(value);
						}
						else if ("Height".equals(name)){
							height = Float.parseFloat(value);
						}
						else if ("Velocity".equals(name)){
							velocity = Float.parseFloat(value);
						}
					}
					else if ("MovingPlatform".equals(element)){
						if ("Width".equals(name)){
							width = Float.parseFloat(value);
						}
						else if ("Height".equals(name)){
							height = Float.parseFloat(value);
						}
						else if ("Velocity".equals(name)){
							velocity = Float.parseFloat(value);
						}
					}
					else if ("Location".equals(element)){
						if ("X".equals(name)){
							x = Float.parseFloat(value);
						}
						else if ("Y".equals(name)){
							y = Float.parseFloat(value);
						}
						else if ("Delay".equals(name)){
							delay = Float.parseFloat(value);
						}
					}
				}
				@Override protected void close(){
					String element = currBranch.pop();
					if ("StartPosition".equals(element)){
						level.iceCube = new IceCube(world,x,y,size,size);
						level.startPos = new Vector2(x,y);
					}
					else if ("Destination".equals(element)){
						level.destination = new DestinationObject(x,y,width,height,entX,entY,entWidth,entHeight);
						level.destinationPos = new Vector2(x,y);
					}
					else if ("CollectableIce".equals(element)){
						colletable = new CollectableIce(world.world, x, y, size, size);
						level.collectables.add(colletable);
					}
					else if ("Fire".equals(element)){
						Fire f = new Fire(world, x,y,size,size);
						level.fires.add(f);
					}
					else if ("Sign".equals(element)){
						sign=new Sign(x, y,width,height,signType);
						level.signs.add(sign);
					}
					else if ("Location".equals(element)){
						Location l = new Location(x, y, delay);
						waypoints.add(l);
					}
					else if ("Fireball".equals(element)){
						fireball = new Fireball(world, waypoints.get(0).position.x, waypoints.get(0).position.y, width, height);
						fireball.setWaypints(waypoints);
						fireball.velocity = velocity;
						level.fireballs.add(fireball);
					}
					else if ("MovingPlatform".equals(element)){
						movingPlatform = new MovingPlatform(world, waypoints.get(0).position.x, waypoints.get(0).position.y, width, height);
						movingPlatform.setWaypints(waypoints);
						movingPlatform.velocity = velocity;
						level.movingPlatforms.add(movingPlatform);
					}

					
				}
			}.parse(LevelFile);
		}
		catch (IOException e){
			throw new GdxRuntimeException("Error Parsing TMX file", e);
		}
		
		return level;
	}

}
